package thread.synchroCode;

import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.LongAdder;

/* 问题：
1。 有二十个账户。每个账户初始余额10000元。
2。 有十个转账线程，对二十个账户中的两个随机选取账户进行转账，转账额度100以内正整数随机数。
3。 每个线程执行100次转账操作。
4。 最后请打印出二十个账户的余额。
*/
public class AliFirstInterview {
  public static void main(String[] args) throws InterruptedException {
    Transfer transfer = new Transfer();
    CountDownLatch countDownLatch = new CountDownLatch(10);
    for (int i = 0; i < 10; i++) {
      new Thread(()-> {
        for (int i1 = 0; i1 < 1000; i1++) {
          transfer.transferMoney();
        }
        countDownLatch.countDown();
      }).start();
    }
    countDownLatch.await();
    transfer.printMoney();
  }

  public static class Transfer{
    public List<Account> accounts;
    SecureRandom r = new SecureRandom();

    public Transfer() {
      accounts = new ArrayList<>();
      for (int i = 0; i < 20; i++) {
        Account account = new Account(10000);
        accounts.add(account);
      }
    }

    public void transferMoney(){
      int money = r.nextInt(100);
      int ran1 = r.nextInt(20);
      int ran2 = r.nextInt(20);
      while (ran1 == ran2){
        ran2 = r.nextInt(20);
      }
      Account account1 = accounts.get(ran1);
      Account account2 = accounts.get(ran2);
      account1.increaseMoney(money);
      account2.decreaseMoney(money);
    }

    public void printMoney() {
      int sum = 0;
      for (int i = 0; i < 20; i++) {
        System.out.println("当前账户为" + i + "余额为：" + accounts.get(i).money);
        sum += accounts.get(i).money.intValue();
      }
      System.out.println("所有账户总余额为" + sum);
    }
  }

  public static class Account1{
    public int money;

    public Account1(int money) {
      this.money = money;
    }

    public synchronized void increaseMoney(int increaseMoney){
      this.money += increaseMoney;
    }

    public synchronized void decreaseMoney(int decreaseMoney){
      this.money -= decreaseMoney;
    }
  }

  public static class Account{  //  可以使用无锁并发
    public LongAdder money;

    public Account(int initMoney) {
      money = new LongAdder();
      money.add(initMoney);
    }

    public void increaseMoney(int increaseMoney){
      money.add(increaseMoney);
    }

    public synchronized void decreaseMoney(int decreaseMoney){
      money.add(-decreaseMoney);
    }
  }

}
